package com.xyy.saas.payment.manage.cores.vo;


import com.xyy.saas.payment.manage.cores.enums.ResultCodeEnum;

import java.io.Serializable;

/**
 * HTTP请求返回格式
 * @Author: wuqiongda
 * @Date: 2019/11/21 13:35
 */
public class ResultVO<T> implements Serializable {
    private static final long serialVersionUID = 74704857074895138L;

    /**
     * 接口操作是否成功状态码，可以参照wiki：<a href='https://wiki.int.ybm100.com/pages/viewpage.action?pageId=291505822' target='_blank'>wiki链接</a>
     */
    private String code;
    /**
     * 提示信息
     */
    private String msg;
    /**‘
     * 中文描述并不是每个请求都有
     */
    private String displayMsg = "";

    /**
     * 需要返回的数据
     */
    private T result;

    public ResultVO() {
        code = ResultCodeEnum.SUCCESS.getCode();
        msg = ResultCodeEnum.SUCCESS.getMsg();
    }

    public ResultVO(T result) {
        this(ResultCodeEnum.SUCCESS, result);
    }

    public ResultVO(String code, String msg) {
        this(code, msg, "");
    }

    public ResultVO(String code, String msg, String displayMsg) {
        this.code = code;
        this.msg = msg;
        this.displayMsg = displayMsg;
    }

    public ResultVO(String code, String msg, String displayMsg, T result) {
        this.result = result;
        this.code = code;
        this.msg = msg;
        this.displayMsg = displayMsg;
    }
    public ResultVO(String code, String msg, T result) {
        this.result = result;
        this.code = code;
        this.msg = msg;
    }

    public ResultVO(ResultCodeEnum resultCodeEnum, T result) {
        this.result = result;
        this.code = resultCodeEnum.getCode();
        this.msg = resultCodeEnum.getMsg();
        this.displayMsg = resultCodeEnum.getDisplayMsg();
    }

    public static <T> ResultVO<T> createSuccess(T result) {
        return new ResultVO(result);
    }

    public static <T> ResultVO<T> createSuccess() {
        ResultVO resultVO = new ResultVO();
        resultVO.setCode(ResultCodeEnum.SUCCESS.getCode());
        resultVO.setMsg(ResultCodeEnum.SUCCESS.getMsg());
        resultVO.setDisplayMsg(ResultCodeEnum.SUCCESS.getDisplayMsg());
        return resultVO;
    }


    public static <T> ResultVO<T> create(ResultCodeEnum resultCodeEnum) {
        return new ResultVO<T>(resultCodeEnum.getCode(), resultCodeEnum.getMsg(), resultCodeEnum.getDisplayMsg());
    }

    public static <T> ResultVO<T> create(String code) {
        if(code == null) {
            return create(ResultCodeEnum.DEFAULT_ERROR);
        }
        ResultCodeEnum[] resultCodeEnums = ResultCodeEnum.values();
        for(ResultCodeEnum resultCodeEnum : resultCodeEnums) {
            if(resultCodeEnum.getCode().equals(code)) {
                return create(resultCodeEnum);
            }
        }
        return create(ResultCodeEnum.DEFAULT_ERROR);
    }

    /**
     * 默认错误
     *
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> ResultVO<T> createError(String code,String msg,T result) {
        if(result == null){
            return new ResultVO<T>( code,  msg, result );
        }
        return new ResultVO<T>( code,  msg, (String) result, result );
    }

    public static <T> ResultVO<T> createError(String code,String msg,String displayMsg, T result) {
        if(result == null){
            return new ResultVO<T>( code,  msg, displayMsg, result );
        }
        return new ResultVO<T>( code,  msg, displayMsg + "-" + result, result );
    }


    public static <T> ResultVO<T> createError(ResultCodeEnum codeEnum,T result) {
        if(result == null){
            return new ResultVO<T>(codeEnum.getCode(), codeEnum.getMsg(),codeEnum.getDisplayMsg(), result);
        }
        return new ResultVO<T>(codeEnum.getCode(), codeEnum.getMsg(),codeEnum.getDisplayMsg() + "-" + result, result);
    }

    /**
     * 默认错误
     *
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> ResultVO<T> createError(String msg) {
        return new ResultVO<T>(ResultCodeEnum.DEFAULT_ERROR.getCode(), msg, ResultCodeEnum.DEFAULT_ERROR.getDisplayMsg());
    }

    public static <T> ResultVO<T> createError(String errorCode, String errorMsg) {
        return new ResultVO<T>(errorCode, errorMsg, errorMsg);
    }

    public static <T> ResultVO<T> createError(ResultCodeEnum codeEnum) {
        return new ResultVO<>(codeEnum.getCode(), codeEnum.getMsg(), codeEnum.getDisplayMsg());
    }

    /**
     * 参数错误
     *
     * @param <T>
     * @return
     */
    public static <T> ResultVO<T> createParamError() {
        return createParamError("");
    }

    public static <T> ResultVO<T> createParamError(String displayMsg) {
        return new ResultVO<T>(ResultCodeEnum.PARAM_ERROR.getCode(), ResultCodeEnum.PARAM_ERROR.getMsg(), displayMsg);
    }

    /**
     * 签名错误
     *
     * @param <T>
     * @return
     */
    public static <T> ResultVO<T> createSignError() {
        return new ResultVO<T>(ResultCodeEnum.SIGN_ERROR.getCode(), ResultCodeEnum.SIGN_ERROR.getMsg(), "签名错误");
    }

    /**
     * 交易单处理失败
     *
     * @param <T>
     * @return
     */
    public static <T> ResultVO<T> createCallbackError() {
        return new ResultVO<T>(ResultCodeEnum.CALLBACK_ERROR.getCode(), ResultCodeEnum.CALLBACK_ERROR.getMsg(), "交易单处理失败");
    }


    /**
     * 由createError代替，Error看着专业一点，并且公司公用组件也是用createError
     *
     * @param msg
     * @param <T>
     * @return
     */
    @Deprecated
    public static <T> ResultVO<T> createFail(String msg) {
        return createError(msg);
    }


    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return this.msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getResult() {
        return this.result;
    }

    public void setResult(T result) {
        this.result = result;
    }

    public String getDisplayMsg() {
        return displayMsg;
    }

    public void setDisplayMsg(String displayMsg) {
        this.displayMsg = displayMsg;
    }

    @Override
    public String toString() {
        return "ResultVO{" +
                "code='" + code + '\'' +
                ", msg='" + msg + '\'' +
                ", displayMsg='" + displayMsg + '\'' +
                ", result=" + result +
                '}';
    }

    public boolean isSuccess() {
        return ResultCodeEnum.SUCCESS.getCode().equals(code);
    }
}